Hvordan kan man lage en for loop eller for løkke i R?

for() loops R løkker

Denne posten beskriver hvordan man kan lage for loops eller for løkker i R. Dette er en enkel, men litt tidkrevende måte å få gjort ting mange ganger på.

Øyvind Bugge Solheim https://www.oyvindsolheim.com (C-REX - Center for Research on Extremism)https://www.sv.uio.no/c-rex/english/
2024-02-26

Løkker/loops

R har flere måter å gjøre den samme operasjonen flere ganger på. for-løkker eller for-loops er en lite effektiv, men ganske intuitiv måte å gjøre det på. I en for-loop spesifiserer vi først hva vi vil løkke over. Vi må altså ha en serie med observasjoner gjerne en vektor i R som vi vil gjøre den samme operasjonen på. Så skriver vi koden som skal kjøres på hvert element i serien. Siden R kjører hver del av loopen etter hverandre er dette mindre effektivt enn å bruke map* og *apply, men ofte raskere å skrive koden fordi det er litt mer rett fram.

Enkelt eksempel

Vi begynner med et enkelt eksempel for å vise hvordan for() virker. I dette første eksempelet tar vi bare en enkel tallrekke og ganger hvert tall med to. Inne i for-løkka lager vi et objekt som er rekka vi regner over. I dette eksempelet kaller vi det i men vi kunne kalt det hva som helst.

# for tallene fra 1 til 10
for(i in 1:10){

#ganger tallet med to:
print(i*2)

}
[1] 2
[1] 4
[1] 6
[1] 8
[1] 10
[1] 12
[1] 14
[1] 16
[1] 18
[1] 20
#her hadde det vært mer effektivt med 2*1:10 direkte

Hvis man skal lagre resultetene fra en loop er det nyttig å lage en liste med list() før man kjører loopen. Det er komplisert og lite nyttig i R å lage nye objekter for hver runde loopen kjører.1 Lister kan vi subsette på ulike måter og lett lage nye objekter inne i lista. Samtidig finnes det mange fine funksjoner for å hente informasjon ut av listene igjen for eksempel map_*-familien fra purrr og rbindlist fra data.table.

Laste inn mange filer

Vi lager et enkelt eksempel der det kan være nyttig å bruke en for-loop. Her laster jeg inn alle csv-filene i en mappe. Vi kan tenke oss at dette for eksempel kan være filer som gjelder resultater for et eller annet for alle månedene i året eller for mange år. Vi lager en loop som henter inn alle filene hver for seg inn i en liste. Så lager vi en data.frame av lista til slutt. Lister er litt enklere å forholde seg til fordi vi kan lage nye elementer bare ved å subsette dem (for eksempel list[“nytt_element”] <- “noe nytt”). Hvis vi skal lage (assign) nye tabeller eller objekter i R er det litt mer kronglete å gi dem logiske navn hvis vi ikke har navnene fra før, men med lister kan vi bare subsette lista og legge til informasjonen vi har henta ut.

Den generelle framgangsmåten for for-looper er ganske grei. Man lager først en liste man vil lagre informasjonen inn i. Så kjører man loopen over en rekke tall eller tekstobjekter.

#laster inn pakker:
library("tidyverse")
library("knitr")


# lager først en tom liste 
for_liste <- list()

I dette eksempelet tenker har vi en mappe med mange csv-filer med informasjon. Vi finner fram til mappa med csv-filene og lager en rekke/vektor med filnavnene.

#mappenavn
mappe<-here::here("_code/Lage en for loop/csv")

# finner filer
filer <- list.files(mappe)

Selve loopen

Så laster vi inn alle filene og legger dem inn i samme liste med en loop. Looper lages med for-funksjonen. I for() spesifiserer vi et variabelnavn og en rekke med verdier vi vil løkke over. Her er det i som er variabelen som skal ha hvert enkeltelement i loopen og filer som er vektoren med alle enkeltelementene. R kjører så koden som følger inne i {} én gang for hvert enkeltelement i filer. Altså vil den først ta det første elementet (her “inntekt_01.csv”) som i. Så kjøres all koden inne i {} som om ivar “inntekt_01.csv”. Når R er ferdig med det kjøres loopen med det andre elementet i filer. Dermed hentes hvert filnavn inn som både listeelementer for_liste[[i]] og inne i read_csv2-funksjonen.

# kjører loop. Vi kjører den over alle filnavnene vi har funnet.
for(i in filer){

# leser hvert filnavn inn i en liste
for_liste[[i]] <- read_csv2(paste0(mappe, "/",i))
}

Siden filene har identiske kolonner så vi kan vi slå sammen lista til en tibble / data.frame.

# siden filene har identiske kolonner kan vi slå sammen lista:
filer_dt <- bind_rows(for_liste, .id = "fil")

Figur over månedlig inntekt

Vi lager så en figur over inntekten for hver måned.

filer_dt %>% 
  #grupperer per måned
  group_by(fil) %>% 
  #regner ut summen av inntekt per måned
  summarize(inntekt=sum(inntekt,na.rm=T)) %>% 
  #starter figur og setter x og y
  ggplot(aes(x=fil,y=inntekt,fill=fil))+
  #lager søyler
  geom_col()+
  #snur aksene så det blir lettere å lese x-merkene
  coord_flip()

Citation

For attribution, please cite this work as

Solheim (2024, Feb. 26). Solheim: Hvordan kan man lage en for loop eller for løkke i R?. Retrieved from https://www.oyvindsolheim.com/code/Lage en for loop/

BibTeX citation

@misc{solheim2024hvordan,
  author = {Solheim, Øyvind Bugge},
  title = {Solheim: Hvordan kan man lage en for loop eller for løkke i R?},
  url = {https://www.oyvindsolheim.com/code/Lage en for loop/},
  year = {2024}
}